作者:祝图net | 来源:互联网 | 2023-08-25 06:47
篇首语:本文由编程笔记#小编为大家整理,主要介绍了Android碎裂的粒子效果相关的知识,希望对你有一定的参考价值。
最近看到一段时间都没怎么更新文章了,一直在学习ios相关内容。偶然间看到一个碎裂的粒子效果,觉得很有意思,就查了查,参考下网上的思路自己撸了个轮子。
好了,说了这么多,先看看效果吧~
![](https://img6.php1.cn/3cdc5/9fdb/bdf/edda14939db2a6b7.jpeg)
依惯例,先说下行文思路吧,首先我们先简单分析下效果,拆分关注点,粒子效果是怎么产生的?我的解决方案就是先获取当前要碎裂的view的缓存视图,然后根据图片获取各个坐标点的颜色值,在整个DecorView盖上一层视图,这个视图就根据获取的颜色值在要碎裂的view的位置来drawCircle
,之后变化圆心和半径以及透明度从而产生碎裂效果。那么,我们要解决的问题已经简化为几个点了,看怎么一个一个将其击破。
一、获取view的视图
二、获取要碎裂的view的位置以及获取各个位置的颜色值
三、变化各个属性值产生动画碎裂效果
一、获取view的视图
获取view的视图也就是要获取这个视图的截图,有两种方式可以来做:
1、可以用Canvas
来获取Bitmap
public Bitmap getBitmapFromView(View view)
Bitmap bmp = Bitmap.createBitmap(webView.getWidth(),
webView.getHeight(), Bitmap.Config.ARGB_8888)
Canvas canvas = new Canvas(bmp)
view.draw(canvas)
return bmp
2、用getDrawingCache
来获取Bitmap
private static Bitmap getCacheBitmapFromView(View view)
final boolean drawingCacheEnabled = true;
view.setDrawingCacheEnabled(drawingCacheEnabled);
view.buildDrawingCache(drawingCacheEnabled);
final Bitmap drawingCache = view.getDrawingCache();
Bitmap bitmap;
if (drawingCache != null)
bitmap = Bitmap.createBitmap(drawingCache);
view.setDrawingCacheEnabled(false);
else
bitmap = null;
return bitmap;
通过这两种方式都可以获取这个视图的图片,而为什么我们要获取这个视图的图片呢,因为要根据这个图片来获取各个位置的颜色值,为之后绘制粒子效果服务。
二、获取要碎裂的view的位置以及获取各个位置的颜色值
获取view的位置,之前使用过getGlobalVisibleRect
方法来获取位置,但很多时候并不是很准确,比如有ActionBar的时候。
Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
之后测试使用getLocationInWindow
这种方式挺不错,这个方法的官方注释为这样写Computes the coordinates of this view in its window.
:
int[] location = new int[2];
view.getLocationInWindow(location);
Rect rect = new Rect(location[0],location[1],location[0]+view.getMeasuredWidth(),location[1]+view.getMeasuredHeight());
在获取视图位置之后,我们要获取各个位置的颜色值来绘制在这片区域内,调用bitmap.getPixel
方法获取各个位置的颜色值:
public static Particle[][] generateParticles(Bitmap bitmap, Rect bound)
int w = bound.width();
int h = bound.height();
int partW_Count = w / Particle.PART_WH;
int partH_Count = h / Particle.PART_WH;
Particle[][] particles = new Particle[partH_Count][partW_Count];
Point point = null;
for (int row = 0; row
三、变化各个属性值产生动画碎裂效果
首先我们要在当前视图上覆盖一层产生碎裂效果的视图:
private void attachToActivity(Activity activity)
ViewGroup rootView = (ViewGroup) activity.getWindow().getDecorView()
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
rootView.addView(this, lp)
将我们要绘制粒子动画效果的添加进布局视图中,然后我们就可以开始绘制了。
开启属性动画,根据动画流程变化Particle的相关属性:
public float cx;
public float cy;
public float radius;
public int color;
public float alpha;
在自定义视图的onDraw
方法,遍历所有我们保存的粒子Particle
,改变相关属性值:
@Override
protected void onDraw(Canvas canvas)
if (mParticleAnimator !=null)
drawParticle(canvas);
public void drawParticle(Canvas canvas)
if(!mParticleAnimator.isRunning())
return;
for (Particle[] particle : mParticleAnimator.getParticles())
for (Particle p : particle)
p.update((Float) mParticleAnimator.getAnimatedValue());
mPaint.setColor(p.color);
mPaint.setAlpha((int) (Color.alpha(p.color) * p.alpha));
canvas.drawCircle(p.cx, p.cy, p.radius, mPaint);
invalidate();
public void update(float factor)
cx = cx + factor * random.nextInt(mBound.width()) * (random.nextFloat() - 0.5f);
cy = cy + factor * (mBound.height()/(random.nextInt(4)+1)) ;
radius = radius - factor * random.nextInt(3);;
if (radius<&#61;0)
radius &#61; 0;
alpha &#61; 1f - factor;
OK&#xff0c;到这里我们就基本实现了这个碎裂效果&#xff0c;整体注意点基本就这么多&#xff0c;我把它简单封装了下&#xff0c;使用方式也很简单&#xff1a;
final ParticleView particleAnimator &#61; new ParticleView(MainActivity.this,3000);
particleAnimator.setOnAnimationListener(new ParticleView.OnAnimationListener()
&#64;Override
public void onAnimationStart(View view,Animator animation)
view.setVisibility(View.INVISIBLE);
&#64;Override
public void onAnimationEnd(View view,Animator animation)
);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener()
&#64;Override
public void onClick(View v)
particleAnimator.boom(v);
);
github地址:ParticleDismissLayout